/* eslint-disable no-param-reassign */
import { constantRoutes, afterRoutes } from "@/router";

const modulesFiles = require.context("@/router/asyncRoutes/", true, /\.js$/);
const asyncRoutes = modulesFiles.keys().reduce((modules, modulePath) => {
    const value = modulesFiles(modulePath);
    modules.push(value.default);
    return modules;
}, []);

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
    if (route.meta && route.meta.roles) {
        return roles.some((role) => route.meta.roles.includes(role));
    }
    return true;
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
    const res = [];

    routes.forEach((route) => {
        const tmp = { ...route };
        if (hasPermission(roles, tmp)) {
            if (tmp.children) {
                tmp.children = filterAsyncRoutes(tmp.children, roles);
            }
            res.push(tmp);
        }
    });

    return res;
}

const stateGlobal = {
    routes: [],
    addRoutes: [],
    TabItems: {},
};

/**
 *  处理顶部TAB布局的路由
 * @param {Array} routers 路由规则数组
 */
function generateTabItems(routers) {
    routers.forEach((route) => {
        if (route.component && route.component.name === "TabLayout") {
            const childs = Object.values(route.children).reduce((previousValue, children) => {
                if (children.meta) {
                    children.meta.activeSelf = !children.hidden;
                    children.meta.activeMenu = route.meta.TabLayoutKey;
                    children.meta.animation = false;
                    children.meta.icon = children.meta.icon || route.meta.icon;
                    previousValue.push({ link: children.path, name: children.meta.title });
                }
                return previousValue;
            }, []);
            stateGlobal.TabItems[route.meta.TabLayoutKey] = childs;
        } else if (route.children) {
            generateTabItems(route.children);
        }
    });
}

export default {
    namespaced: true,
    state: stateGlobal,
    mutations: {
        SET_ROUTES: (state, routes) => {
            state.addRoutes = routes;
            state.routes = [
                ...constantRoutes, // 静态路由
                ...routes, // 处理后路由
                ...afterRoutes, // 末尾静态路由
            ];
        },
    },
    actions: {
    /** @param {Array} roles 用户角色列表  roles [{name:'xxx'}] */
        generateRoutes({ commit }, roles = []) {
            return new Promise((resolve) => {
                const reRolesName = roles.reduce((pv, role) => {
                    pv.push(role.name);
                    return pv;
                }, []);
                generateTabItems(asyncRoutes);
                const accessedRoutes = reRolesName.includes("九条米法")
                    ? asyncRoutes
                    : filterAsyncRoutes(asyncRoutes, reRolesName);
                commit("SET_ROUTES", accessedRoutes);
                resolve(accessedRoutes.concat(afterRoutes));
            });
        },
    },
};
